Main
Edit Profile
My Mods
Logout



Homeworld File Format Documentation
.Lif File Format
By B1FF (lmoloney@relic.com)

© 2000 Relic Entertainment, Inc.

Preamble
The .LiF extension (note the wacky capitalization) is short for "Layered image Format". This format is the image storage method for Homeworld. It is mostly used for textures but also finds use for front end graphics, cursor bitmaps and tutorial button graphics. It actually has two general formats which share a common header. Also released will be the tool we use to create .LiF files. Initially, we supported many different layers for image blending but in an effort to improve loading time and reduce texture usage, we tried crunching a 5-dimensional color space into 8 bits using a lossy quantization algorithm. I'm not going to explain the alogorithm because I mostly forget how it worked - and I created it! Anyhow, here's the file format.

.LiF File Header
Here is the header to the file:

//format for the .LiF files
typedef struct
{
char ident[8]; //compared to "Willy 7"
sdword version; //version number
sdword flags; //to plug straight into texreg flags
sdword width, height; //dimensions of image
crc32 paletteCRC; //a CRC of palettes for fast comparison
crc32 imageCRC; //crc of the unquantized image
ubyte *data; //actual image
color *palette; //palette for this image
ubyte *teamEffect0, *teamEffect1; //palettes of team color effect
// sdword nSizes; //number of sizes encoded
// udword image[LLC_NumberImages]; //offset-pointers to the individual images (from end of this header)
}
lifheader;

Ident - self-explanatory.
Version - 0x104 as of release. Will stay here.
Flags - bitmasks of the following:
#define TRF_Alpha 0x00000008 //alpha channel image
#define TRF_TeamColor0 0x00000010 //team color flags
#define TRF_TeamColor1 0x00000020
All other bitmasks ignored. TeamColor0 is the base color, TeamColor1 is the stripe color.
Width, height - size of image.
PaletteCRC - 32-bit CRC of palette. All palette CRC's for a ship should be the same and unique compared to all other ships. Important for shared palettes!
ImageCRC - 32-bit CRC of image. Ignore this. Only used for creation.
Data - offset to image data
Palette - offset to palette (if a paletted image, 0 otherwise)
TeamEffect0 - Offset to 'base color influence image or palette'.
TeamEffect1 - Offset to 'stripe color influence image or palette'.

If the image has an alpha channel, the image is loaded as an RGBA image. The palette is ignored and the TeamEffect0/1 buffers are blended with the main image using this algorithm:

/*-----------------------------------------------------------------------------
Name : trBufferColorRGB
Description : Colorize an image (or palette) based upon team effect buffers
Inputs : dest - where to put the colorized image
source - where to read the uncolorized version
teamEffect0,1 - team color effect buffers
teamColor0,1 - team colors to colorize to
size - size fo buffer, in pixels
flags - texreg flags telling us how to colorize the image
effectScalar0, effectScalar1 - scalar of
the team effect values to be read.
Outputs :
Return : void
----------------------------------------------------------------------------*/
void trBufferColorRGB(color *dest, color *source,
ubyte *teamEffect0, ubyte *teamEffect1,
color teamColor0, color teamColor1,
sdword size, udword flags,
real32 effectScalar0, real32 effectScalar1)
{
real32 teamRed0 = colUbyteToReal(colRed(teamColor0));
real32 teamRed1 = colUbyteToReal(colRed(teamColor1));
real32 teamGreen0 = colUbyteToReal(colGreen(teamColor0));
real32 teamGreen1 = colUbyteToReal(colGreen(teamColor1));
real32 teamBlue0 = colUbyteToReal(colBlue(teamColor0));
real32 teamBlue1 = colUbyteToReal(colBlue(teamColor1));
real32 redSource, greenSource, blueSource, redDest, greenDest, blueDest, effectReal0, effectReal1;

while (size > 0)
{
//read the info from buffers into floating point
redSource = colUbyteToReal(colRed(*source));
greenSource = colUbyteToReal(colGreen(*source));
blueSource = colUbyteToReal(colBlue(*source));
if (bitTest(flags, TRF_TeamColor0))
{
effectReal0 = min(1.0f, colUbyteToReal(*teamEffect0) * effectScalar0);
}
else
{
effectReal0 = 0.0f;
}
if (bitTest(flags, TRF_TeamColor1))
{
effectReal1 = min(1.0f, colUbyteToReal(*teamEffect1) * effectScalar1);
}
else
{
effectReal1 = 0.0f;
}
//blend
redDest = redSource * (1.0f - effectReal0) + teamRed0 * effectReal0;
redDest = redDest * (1.0f - effectReal1) + teamRed1 * effectReal1;
greenDest = greenSource * (1.0f - effectReal0) + teamGreen0 * effectReal0;
greenDest = greenDest * (1.0f - effectReal1) + teamGreen1 * effectReal1;
blueDest = blueSource * (1.0f - effectReal0) + teamBlue0 * effectReal0;
blueDest = blueDest * (1.0f - effectReal1) + teamBlue1 * effectReal1;
//write back
*dest = colRGBA(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest), colAlpha(*source));
//update pointers
size--;
dest++;
source++;
teamEffect0++;
teamEffect1++;
}
}

Note that a paletted image has its palette blended with its team color palettes using the same algorithm.

So there you have the file format. This file format is actually of little use, however, unless you want to extract the art from Homeworld. To create .LiF files, Relic will release a command-line tool we used to create these files.

.LiF Listing file (textures.ll)
Textures.ll is a database of textures used to speed up the measurement of textures for texture packing. While you don't have to add your textures to this database, you might find it useful to look at. The same tool we use to make the .LiF files maintains this database.

Creating .LiF files.
.Lif files are created from Adobe Photoshop files (.PSD). These files support the layering and blending we so wanted. The ordering of blending is the same in our .LiF exporter as in Photoshop. The names of layers determines their usage. Following is the recognized names for layers and their common blending mode.
-"COL 1", "COL1" - base color layer. Usually overlay mode.
-"COL 2", "COL2" - can you guess?
-"TEX" - The actual texture layer. Usually base layer, normal blending.
-"LAB", "PB", "PW", "DIRT" - detail layers
-"ALPHA" alpha channel, if there is one. Use multiply and stick it on top of everything.

When you have a list of textures you want to "quatnize" into .LiF files, use the following batch file, onebunchalifs.bat, or some derivative thereof:

@pushd

@if "%1"==%1 goto about

@cd\homeworld

@if exist datasrc\%1\dependtex.mif del datasrc\%1\dependtex.mif > NUL
@echo # > datasrc\%1\dependtex.mif
@for %filename in (datasrc\%1\*.psd) echo TEXTURES += %@name[%filename].lif >> datasrc\%1\dependtex.mif
@liflist q data\textures.ll datasrc\%1\dependtex.mif
@del datasrc\%1\dependtex.mif > NUL
goto end

:about
@echo USAGE: OneBunghaLifs

:end

@popd

For example, to make the highest LOD of the R1 Support Frigate, type:

OneBunchaLifs R1\AdvanceSupportFrigate\Rl0\LOD0
   
All contents Copyright © 2001 Relic Entertainment Inc. All rights reserved. Privacy Statement.
send to a friend
relic forums